<?php

namespace App\Http\Model;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class Family extends Base
{
    protected $table = "family"; //家族表
    protected $user_table = "family_user"; //家族成员表
    protected $role_table = 'family_role'; //家族角色表
    protected $apply_user_table = "family_user_apply"; //申请加入家族记录表
    protected $assign_user_table = 'family_assign_user'; //家族任命表
    protected $union_table = 'union';
    protected $family_follow_table = 'family_follow';

    protected $union_supply_total = "FAMILY:TOTAL:SUPPLY";
    protected $kick_user_to_family_key = "FAMILY:USER:KICK";

    protected $redis_family_create_times = 'FAMILY:CREATE:TIMES:';
    protected $redis_family_update_name = 'FAMILY:UPDATE:NAME:';
    protected $redis_family_dissolve_code = 'FAMILY:DISSOLVE:CODE:';
    protected $adapt_size ;
    protected $redis_family_role = 'FAMILY:ROLE';
    protected $redis_family_user_ids = 'FAMILY:USER:IDS';
    protected $redis_family_follow = 'FAMILY:USER:FOLLOW';
    protected $redis_family_special_idcard = 'FAMILY:SPECIAL:IDCARD'; //特殊身份证号，同一个实名认证账户可以创建多个家族

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
        $adapters = explode(',',Redis::HGET('IMAGE:ADAPT' ,'family'));
        $this->adapt_size = !empty($adapters) && count($adapters)>1 ? $adapters[1] : 480;
    }

    //创建家族
    public function createFamily($data = [])
    {
        $times = Redis::get($this->redis_family_create_times .date('Ymd').':'.$data['uuid']) ?? 0;
        if($times>=3){
            return -1;
        }
        $res = DB::table($this->table)->insertGetId($data);
        if($res){
            Redis::setex($this->redis_family_create_times.date('Ymd').':'.$data['uuid'] ,strtotime(date('Y-m-d',strtotime('+1 day')))-time()-1,$times+1);
            return $res;
        }
        return 0;
    }

    /**添加家族成员
     * @param $data
     * @return int
     */
    public function createFamilyUser($data)
    {
        $this->clearFamilyCache($data['family_id']);
        return DB::table($this->user_table)->insertGetId($data);
    }

    /**判断用户是否加入过家族
     * @param $user_id
     * @return bool
     */
    public function getFamilyUser($user_id){
        $res = DB::table($this->user_table)->where('user_id' ,$user_id)->first();
        return $res ? $res->family_id : 0;
    }

    /*
     * 用户申请记录
     * */
    public function applyUserLog($user_id, $family_id = '')
    {
        $where['user_id'] = $user_id;
        if ($family_id) $where['family_id'] = $family_id;
        $res = DB::table($this->apply_user_table)->where($where)->get();
        return $this->objToArray($res);
    }

    /**删除申请记录
     * @param $user_id
     * @return int
     */
    public function delApplyLogToUser($user_id)
    {
        $where['user_id'] = $user_id;
        return DB::table($this->apply_user_table)->where($where)->delete();
    }
    /**获取家族管理员的用户id
     * @param $family_id
     * @return mixed
     */
    public function getFamilyAdminUserIds($family_id)
    {
        $res = DB::table($this->user_table)
            ->where('family_id',$family_id)
            ->where('role_id','>',0)
            ->orderBy('role_id', 'asc')
            ->select('user_id')
            ->get();
        return $this->objToArray($res);
    }

    /*
    * 获取家族成员
    * $family_id  家族id
    * */
    public function getFamilyUserList($family_id, $search)
    {
        $where['family_id'] = $family_id;
        $where[] = ['role_id', '>', '0'];
        $whereOr = $where;

        if ($search) {
            $where[] = ['uuid', 'like', "%$search%"];
            $whereOr[] = ['nickname', 'like', "%$search%"];
        }
        $role_user = DB::table($this->user_table)
            ->where($where)
            ->orWhere($whereOr)
            ->leftJoin("user", $this->user_table . ".user_id", "=", "user.user_id")
            ->orderBy('role_id', 'asc')
            ->orderBy($this->user_table .'.created_at','asc')
            ->select('portrait', 'user.user_id', 'role_id', 'family_id', 'uuid', 'gender', 'nickname', $this->user_table . '.created_at')
            ->get();
        $res['role_user'] = $this->objToArray($role_user);
        $role = $this->getRolesList();
        foreach ($res['role_user'] as &$v) {
            $v['portrait'] = build_image(json_decode($v['portrait'])[0]);
            $v['role_name'] =  isset($role[$v['role_id']]) ? $role[$v['role_id']] : '';
        }
        $whereUser['family_id'] = $family_id;
        $whereUser[] = ['role_id', '=', '0'];

        $whereUserOr = $whereUser;
        if ($search) {
            $whereUser[] = ['uuid', 'like', "%$search%"];
            $whereUserOr[] = ['nickname', 'like', "%$search%"];
        }
        $user = DB::table($this->user_table)
            ->where($whereUser)
            ->orWhere($whereUserOr)
            ->leftJoin("user", $this->user_table . ".user_id", "=", "user.user_id")
            ->orderBy('role_id', 'asc')
            ->select('portrait', 'user.user_id', 'role_id', 'family_id', 'uuid', 'gender', 'nickname', $this->user_table . '.created_at')
            ->get();
        $res['user'] = $this->objToArray($user);
        foreach ($res['user'] as &$vv) {
            $vv['portrait'] = build_image(json_decode($vv['portrait'])[0]);
            $vv['role_name'] =  isset($role[$vv['role_id']]) ? $role[$vv['role_id']] : '';
        }
        return $res;
    }

    /**获取家族所有成员id
     * @param $family_id
     * @return array
     */
    public function getFamilyUserIds($family_id ,$only_user_ids = true){
        if($only_user_ids){
            $family_user_ids = Redis::hget($this->redis_family_user_ids ,$family_id);
            if(!empty($family_user_ids)){
                return json_decode($family_user_ids ,true);
            }else{
                $res = DB::table($this->user_table)->where('family_id' ,$family_id)->get();
                $res = $this->objToArray($res);
                $data = array_column($res ,'user_id');
                Redis::HSET($this->redis_family_user_ids ,$family_id ,json_encode($data));
                return $data;
            }
        }
        $res = DB::table($this->user_table)->where('family_id' ,$family_id)->get();
        return  $this->objToArray($res);
    }
    //查询家族任命角色日志
    public function getAssignFamilyRoleLog($family_id, $user_id, $role_id)
    {
        $where['family_id'] = $family_id;
        $where['user_id'] = $user_id;
        $where['role_id'] = $role_id;
        $res = DB::table($this->assign_user_table)->where($where)->first();
        return $this->objToArray($res);
    }

    //生成任命记录
    public function addAssignUserLog($family_id, $user_id, $role_id)
    {
        $data['family_id'] = $family_id;
        $data['user_id'] = $user_id;
        $data['role_id'] = $role_id;
        $id = DB::table($this->assign_user_table)->insertGetId($data);
        if($id){
            return DB::table($this->user_table)->where(['family_id'=>$family_id ,'user_id'=>$user_id])
                ->update(['role_id'=>$role_id]);
        }
        return  0;
    }

    //修改家族用户角色
    public function updateUserRole($family_id, $user_id, $role_id)
    {
        $where['family_id'] = $family_id;
        $where['user_id'] = $user_id;
        $data['role_id'] = $role_id;
        return DB::table($this->user_table)->where($where)->update($data);
    }

    /**获取公会角色列表
     * @return array
     */
    public function getRolesList()
    {
        $data = Redis::get($this->redis_family_role);
        if(!empty($data)){
            return json_decode($data ,true);
        }
        $res = DB::table($this->role_table)->orderBy('id','asc')->get(['id','name']);
        $res = $this->objToArray($res);
        $data = array();
        foreach ($res as $r){
            $data[$r['id']] = $r['name'];
        }
        if(!empty($data)){
            Redis::set($this->redis_family_role,json_encode($data));
        }
        return $data;
    }

    //踢出用户
    public function kickUser($user_id)
    {
        $key = $this->kick_user_to_family_key . $user_id;
        return Redis::SETEX($key, 432000, time());
    }

    /**成员退出家族
     * @param $family_id
     * @param string $user_id
     * @return int
     */
    public function quitUserFamily($family_id, $user_id = '')
    {
        $where['family_id'] = $family_id;
        if ($user_id) {
            $where['user_id'] = $user_id;
        }
        $this->clearFamilyCache($family_id);
        return DB::table($this->user_table)->where($where)->delete();
    }

    /**获取用户角色信息
     * @param $user_id
     * @param $family_id
     * @return mixed
     */
    public function getUserRole($user_id, $family_id)
    {
        $where['user_id'] = $user_id;
        $where['family_id'] = $family_id;
        $res = DB::table($this->user_table)->where($where)
            ->leftJoin("family_role", "family_role.id", "=", "family_user.role_id")
            ->first();
        return $this->objToArray($res);
    }
    /**编辑家族
     * @param $id
     * @param array $data
     * @return int
     */
    public function editFamily($id, $data = [])
    {
        $where['id'] = $id;
        return DB::table($this->table)->where($where)->update($data);
    }

    //验证用户是否被踢120h以内
    public function checkUserDelTime($user_id)
    {
        $key = $this->kick_user_to_family_key . $user_id;
        return Redis::get($key);
    }

    //根据家族id获取家族信息
    public function getFamilyInfoByFid($family_id ,$is_build_image = true)
    {
        $where['stop'] = 1;
        $where['id'] = $family_id;
        $res = DB::table($this->table)->where($where)->first();
        if(!empty($res) && $is_build_image){
            $res->portrait = build_image($res->portrait);
        }
        return $this->objToArray($res);
    }

    //根据族长id获取家族信息
    public function getFamilyInfo($user_id)
    {
        if(is_array($user_id)){
            $res = DB::table($this->table)->whereIn('user_id',$user_id)->first();
            return $this->objToArray($res);
        }
        $where['user_id'] = $user_id;
        $res = DB::table($this->table)->where($where)->first();
        if(!empty($res)){
            $res->portrait = build_image($res->portrait);
        }
        return $this->objToArray($res);
    }

    /**获取家族所有成员
     * @param $family_id
     * @param bool $num
     * @return \Illuminate\Support\Collection|int|mixed
     */
    public function getUserNum($family_id,$num=true){
        $res = DB::table($this->user_table)
            ->where('family_id' ,$family_id)
            ->orderBy('created_at','desc')
            ->get();
        $res = $this->objToArray($res);
        if($num){
            return count($res);
        }
        return $res;
    }

    /* 用户家族
     * $user_id 用户id
     * $family_id  家族id
     * */
    public function applyFamilyToUser($user_id, $family_id)
    {
        $data['user_id'] = $user_id;
        $data['family_id'] = $family_id;
        return DB::table($this->apply_user_table)->insertGetId($data);
    }

    /*
     * 删除家族
     * $user_id  会长id
     * $family_id  家族id
     * */
    public function delFamily($family_id, $user_id)
    {
        $where['id'] = $family_id;
        $where['user_id'] = $user_id;
        return DB::table($this->table)->where($where)->delete();
    }

    //家族职务对应人数
    public function familyRoleCountNum($family_id)
    {
        $where['family_id'] = $family_id;
        $res = DB::table($this->user_table)->where($where)
            ->leftJoin("family_role", "family_role.id", "=", "family_user.role_id")
            ->selectRaw('role_id, count(zb_family_user.id) as count_role,upper')
            ->groupBy('role_id')
            ->get();
        return $this->objToArray($res);
    }

    /**获取角色信息
     * @param $role_id
     * @return mixed
     */
    public function getRoleInfo($role_id)
    {
        $where['id'] = $role_id;
        $res = DB::table($this->role_table)->where($where)->first();
        return $this->objToArray($res);
    }
    public function getUnionRank($total)
    {
        $sql = "select * from zb_union_rank where start_value <= $total and end_value >=$total";
        $res = DB::select($sql);
        return $this->objToArray($res);

    }

    public function searchUnion($keyWords, $page, $limit)
    {
        $db = DB::table('union')
            ->where('uuid', '=', $keyWords)
            ->orWhere('name', 'like', "%$keyWords%");

        // 总条数
        $totalCount = $db->count('id');

        // 总数
        $result = $db->offset($page * $limit)
            ->limit($limit)
            ->get(['id', 'uuid', 'portrait', 'name', 'notice', 'desc', 'liang']);
        $result = $this->objToArray($result);
        foreach ($result as $k => $v) {
            $result[$k]['portrait'] = getPicDomain() . $v['portrait'];
        }
        return $this->checkPageData($page, $limit, 0, $result);

    }
    /**判断家族/家族名称是否存在
     * @param $name
     * @return mixed
     */
    public function checkUnionAndFamilyName($name){
        $res = DB::table($this->union_table)
            ->where('name',$name)
            ->first();
        if(empty($res->id)){
            $res = DB::table($this->table)
                ->where('name',$name)
                ->first();
        }
        return $this->objToArray($res);
    }

    public function setFamilyInfo($input,$add_time = true){
        $family_id = $input['family_id'];
        if(isset($input['name'])){
            $arr['name'] = $input['name'];
        }
        if(isset($input['portrait'])){
            $arr['portrait'] = $input['portrait'];
        }
        if(isset($input['declaration'])){
            $arr['declaration'] = $input['declaration'];
        }
        if(!empty($arr)){
            $res = DB::table($this->table)
                ->where("id", $family_id)
                ->update($arr);
        }
        if(!empty($arr['name']) && $add_time){
            Redis::SETEX($this->redis_family_update_name.$family_id,24*60*60 ,time());
        }
        return empty($res) ? 0 : $res;
    }

    public function getUpdateNameTime($union_id){
        return Redis::get($this->redis_family_update_name.$union_id);
    }
//    校验会长身份，发送短信验证码
    //redis存储
    public function redisCache($key,$value,$expire_time = 300){
        Redis::setex($key,$expire_time,$value);
        return true;
    }
    //redis存储获取
    public function redisCacheGet($key){
        return Redis::get($key);
    }
    //redis 存储删除
    public function redisCacheDel($key){
        return Redis::del($key);
    }

    /**获取家族列表
     * @param $search
     * @param int $page
     * @param int $limit
     * @return mixed
     */
    public function getFamily($search='',$page = 0,$limit = 10){
        $where[] = ['stop', '=', '1'];
        $whereOr = $where;
        if (!empty($search)) {
            $where[] = ['uuid', 'like', "%$search%"];
            $whereOr[] = ['name', 'like', "%$search%"];
        }
        $res = DB::table($this->table)
            ->where($where)
            ->orWhere($whereOr)
            ->orderBy('created_at', 'desc')
            ->offset($page*$limit )
            ->limit($limit)
            ->get();
        return $this->objToArray($res);
    }

    /**生成解散码
     * @param $family_id
     * @return string
     */
    public function generateDissolveCode($family_id){
        $code = md5(microtime(true).rand(1,99999));
        Redis::SETEX($this->redis_family_dissolve_code.$family_id, 24*60*60 ,$code);
        return $code;
    }

    /**获取解散码
     * @param $family_id
     * @return int
     */
    public function getDissolveCode($family_id){
        $code = Redis::get($this->redis_family_dissolve_code.$family_id);
        return empty($code) ? '' : $code;
    }

    /**压缩图片
     * @param $image
     * @return array|string
     */
    public function buildUnionImage($image){
        return build_adapt_images($image ,$this->adapt_size);
    }

    /**获取指定用户角色
     * @param $user_ids
     * @param $family_id
     * @return mixed
     */
    public function getUsersRole($user_ids, $family_id)
    {
        $res = DB::table($this->user_table)
            ->where('family_id' ,$family_id)
            ->whereIn('user_id' ,$user_ids)
            ->leftJoin("family_role", "family_role.id", "=", "family_user.role_id")
            ->get();
        $res = $this->objToArray($res);
        return !empty($res) ? array_column($res ,null ,'user_id') : [];
    }

    public function clearFamilyCache($family_id){
        Redis::HDEL($this->redis_family_user_ids ,$family_id);
    }

    public function getFamilyByIds($search='',$family_ids ,$page ,$limit){
        $where =$whereOr = [];
        if (!empty($search)) {
            $where[] = ['uuid', 'like', "%$search%"];
            $whereOr[] = ['name', 'like', "%$search%"];
        }
        $res = DB::table($this->table)
            ->where('stop' ,1)
            ->whereIn('id' ,$family_ids)
            ->where($where)
            ->orWhere($whereOr)
            ->orderBy('created_at', 'desc')
            ->offset($page*$limit )
            ->limit($limit)
            ->get();
        return $this->objToArray($res);
    }

    /**插入/删除关注家族
     * @param $type
     * @param $data
     * @return int
     */
    public function curdFamilyFollow($type ,$data){
        $res = 0;
        switch ($type){
            case 1:
                $res = DB::table($this->family_follow_table)->insertGetId($data);
                break;
            case 2:
                $res = DB::table($this->family_follow_table)->where($data)->delete();
                break ;
            default:
                return 0;
        }
        Redis::hdel($this->redis_family_follow ,$data['user_id']);
        return  $res;
    }

    /**获取用户关注的家族id
     * @param $user_id
     * @return array
     */
    public function getFollowFamilyIds($user_id){
        $res = Redis::hget($this->redis_family_follow ,$user_id);
        if(!empty($res)){
            return  json_decode($res ,true);
        }
        $res = DB::table($this->family_follow_table)->where('user_id' ,$user_id)->get();
        $res = $this->objToArray($res);
        if(!empty($res)){
            Redis::hset($this->redis_family_follow ,$user_id , json_encode(array_column($res ,'family_id')));
        }
        return empty($res) ? [] : array_column($res ,'family_id');
    }

    /**用户是否关注管家族
     * @param $user_id
     * @param $family_id
     * @return int 0 未关注 1 关注
     */
    public function getIsFollowFamily($user_id ,$family_id){
        $res = Redis::hget($this->redis_family_follow ,$user_id);
        if(!empty($res)){
            $res = json_decode($res ,true);
            return in_array($family_id ,$res) ? 1 : 0;
        }
        $res = DB::table($this->family_follow_table)
            ->where(array('user_id'=>$user_id ,'family_id'=>$family_id))
            ->first();
        $res = $this->objToArray($res);
        return empty($res['id']) ? 0 : 1;
    }

    /**获取申请记录
     * @param $family_id
     * @param $page
     * @param $pageSize
     * @return mixed
     */
    public function getInviteLog($family_id ,$page ,$pageSize){
        $res = DB::table($this->apply_user_table)
            ->where('family_id',$family_id)
            ->offset(($page) * $pageSize)
            ->limit($pageSize)
            ->get();
        return $this->objToArray($res);
    }

    /**获取家族总人数
     * @param $family_id
     * @return mixed
     */
    public function getFamilyUserNum($family_id){
        $res = DB::table($this->user_table)
            ->select(DB::raw('count(user_id) as num'))
            ->where('family_id' ,$family_id)
            ->first();
        return $this->objToArray($res);
    }

    /**校验用户是否是特殊身份证号
     * @param $idcard
     * @return mixed
     */
    public function isSpecialIdCard($idcard){
        return Redis::HGET($this->redis_family_special_idcard ,$idcard) ?? 0;
    }
}
